<?php
/**
 * 订单模块后台 Service
 *
 * 订单模块后台 Service的注意及说明
 * 以下use模块请不要互相伤害
 *
 * @author    xiecz <xiecz@yunys.com.cn>
 * @copyright 2016 QuanZhouYunYiShang Inc.
 */
namespace App\Services\Order;
use Log;
use App\Services\Tool\DataBase\SQL;
use App\Services\Tool\GeneralTool;
use App\Services\Tool\Order\OrderTool;
use App\Services\Tool\ExpressTool;
use App\Services\Tool\Zip;
use App\Services\Tool\Pay\PayTool;

class OrderBackstage{

    function __construct(OrderTool $orderTool,
                         ExpressTool $express,
                         Zip $zip){
        $this->orderTool = $orderTool;
        $this->express   = $express;
        $this->zip       = $zip;
    }

    /**
        订单列表
        参数：
            order_id    订单号         orders
            state       订单状态       orders
            consignee   收货人         order_express
            address     详细地址       order_express **
            phone       电话           order_express
            express_id  配送方式       order_express
            time_range  下单时间范围    orders
            pay_type    支付方式       orders
     */
    function order_list($input){
        $arr = [];
        foreach($input as $k=>$v){
            if($k == 'state' || $k == 'order_id' || $k == 'time_range' || $k == 'pay_type' || $k == 'platform' || $k == 'worksheet_id' ||
                $k == 'channel_id')
                $arr['orders'][$k] = $v;
            else if($k == 'consignee' || $k == 'phone' || $k == 'express_id')
                $arr['order_express'][$k] = $v;
        }
        if(isset($arr['orders']['state'])){
            $state = json_decode($arr['orders']['state'],true);

            if(is_array($state)){
                unset($arr['orders']['state']);
                if(isset($state['is_cancel'])) $arr['orders']['is_cancel'] = $state['is_cancel'];
                if(isset($state['state']))  $arr['orders']['state'] = $state['state'];
            }
        }
        $orders = $this->orderTool->order_list_lists_backstage($arr);
        $orders->appends($input)->render();
        return $orders;
    }

    /**
        订单统计
        参数：
            order_id    订单号         orders
            state       订单状态       orders
            consignee   收货人         order_express
            address     详细地址       order_express **
            phone       电话           order_express
            express_id  配送方式       order_express
            time_range  下单时间范围    orders
            pay_type    支付方式       orders
     */
    function order_statistics($input){
        if(!isset($input['time_range'])) return [];
        $arr = [];
        foreach($input as $k=>$v){
            if(($k == 'order_id' || $k == 'pay_type' || $k == 'platform' ||
                $k == 'channel_id') && $v != '')
                $arr['orders'][$k] = $v;
        }

        $orders = $this->orderTool->order_statistics($input);
        return $orders;
    }

    /**
        生成Excel
     */
    function create_excel($input){
        $arr = [];
        foreach($input as $k=>$v){
            if($k == 'state' || $k == 'order_id' || $k == 'time_range' || $k == 'pay_type' || $k == 'platform')
                $arr['orders'][$k] = $v;
            else if($k == 'consignee' || $k == 'phone' || $k == 'express_id')
                $arr['order_express'][$k] = $v;
        }
        if(isset($arr['orders']['state'])){
            $state = json_decode($arr['orders']['state'],true);
            if(is_array($state)){
                $arr['orders']['is_cancel'] = isset($state['is_cancel']) ? $state['is_cancel'] : 0;
                $arr['orders']['state']     = isset($state['state']) ? $state['state'] : 0;
            }
        }
        $rows   = $this->orderTool->order_list_lists_from_excel($arr);
        $orders = $this->orderTool->create_order_excel($rows);
        return GeneralTool::createResult($orders,'M00000');
    }

    /**
        订单详情
        参数：
            order_id        订单编号
     */
    function order_detail($input){
        if(!isset($input['order_id'])) return (object)[];
        $order = $this->orderTool->order_detail_backstage($input['order_id']);//dd($order);
        return $order;
    }

    /**
        修改订单物流信息
        参数：
            order_id            订单编号
            express_id          物流公司代码
            order_express_id    物流单号
     */
    function order_send($input){
        try{
            //判断参数是否足够
            if(!isset($input['order_id'])||
               !isset($input['express_id'])||
               !isset($input['order_express_id']))
                return GeneralTool::createResult('','M00002');
            //判断订单是否存在
            $order  = SQL::first(['table'=>'orders',
                                  'where'=>['order_id'=>$input['order_id']]]);
            if(!isset($order)) return GeneralTool::createResult('','M05054');
            $express_name   = SQL::pluck(array('table'=>'express',
                                               'where'=>array('express_id'=>$input['express_id']),
                                               'pluck'=>'express_name'));
            if(!isset($express_name)) return GeneralTool::createResult('','M05055');
            $input['express_name'] = $express_name;
            //修改订单物流信息
            $result = $this->orderTool->order_send($order, $input);
            if($result == 'M00000'){
                //订阅物流信息
                $re = $this->express->subscribeExpressInfo($input['express_id'],$input['order_express_id']);
            }

            return GeneralTool::createResult('',$result);
        }catch(\Exception $e){
            Log::info($e);
            SQL::CatchDo();
            return GeneralTool::createResult('','M00003');
        }finally{
            SQL::FinallyDo();
        }
    }

    /**
        修改订单后退备注
        参数：
            order_id            订单编号
            back_message        后台备注
     */
    function update_order_back_message($input){
        if(!isset($input['order_id']) || !isset($input['back_message']))
            return GeneralTool::createResult('','M00002');
        $input['back_message'] = trim($input['back_message']) != '' ? bin2hex($input['back_message']) : '';

        $result = SQL::update(['table' => 'orders',
                               'where' => ['order_id'     => $input['order_id']],
                               'update'=> ['back_message' => $input['back_message']]]);
        return GeneralTool::createResult('', ($result ? 'M00000' : 'M00001'));
    }

    /**
        修改订单收获信息
        参数：
            order_id            订单编号
            consignee           姓名
            phone               手机号
            address             详细地址
     */
    function update_order_rece($input){
        if(!isset($input['order_id']) ||
            !isset($input['consignee']) ||
            !isset($input['phone']) ||
            !isset($input['address']))
            return GeneralTool::createResult('','M00002');

        $order  = SQL::first(['table'=>'orders',
                              'where'=>['order_id'=>$input['order_id']]]);
        if(!isset($order)) return GeneralTool::createResult('','M05054');
        if($order->send_state == 1) return GeneralTool::createResult('','M05056');
        $result = $this->orderTool->update_order_rece($input);
        return GeneralTool::createResult('', $result);
    }

    /**
        创建订单打印图zip包
        参数：
            order_id            订单编号
     */
    function create_order_zip($input){
        if(!isset($input['order_id'])) return GeneralTool::createResult('','M00002');
        $data = $this->orderTool->get_order_prints_to_zip($input['order_id']);

        $result = $this->zip->createZip(array('zip_name'=>($input['order_id'].'.zip'),
                                              'type'=>'order',
                                              'file'=>$data));

        if(isset($result['state'])&&$result['state']=='00'){
            return GeneralTool::createResult($result,'M00000');
        }
        return ['state'=>'M00001','message'=>$result['msg'],'result'=>$result];
    }

    /**
        修改打印进度
        参数：
            order_detail_number 订单商品编号
            state               状态
     */
    function update_order_print_state($input){
        if(!isset($input['order_detail_number']) || !isset($input['state']))
            return GeneralTool::createResult('','M00002');
        $arr  = [];
        switch($input['state']){
            case 1:
                $arr['where']['print_state']  = 0;
                $arr['update']['print_state'] = 1;
                $arr['update']['begin_time']  = time();
                break;
            case 2:
                $arr['where']['print_state']  = 1;
                $arr['update']['print_state'] = 2;
                $arr['update']['end_time']    = time();
                break;
            default:
                return GeneralTool::createResult('','M00004');
        }
        $arr['where']['order_detail_number'] = $input['order_detail_number'];

        $result = SQL::update(['table' => 'order_details',
                               'where' => $arr['where'],
                               'update'=> $arr['update']]);
        return GeneralTool::createResult('',($result ? 'M00000' : 'M00001'));
    }

    /**
     * 关闭工单
     * 参数：
     *     order_id             订单编号
     *     worksheet_id         工单号
     */
    function close_worksheet($input){
        if(!isset($input['order_id']) ||
            !isset($input['worksheet_id']))
            return GeneralTool::createResult('','M00002');
        $result = SQL::update(['table'  => 'orders',
                               'where'  => ['order_id'          => $input['order_id'],
                                            'worksheet_id'      => $input['worksheet_id'],
                                            'enabled_worksheet' => 1],
                               'update' => ['enabled_worksheet' => 0]]);
        return GeneralTool::createResult('', ($result ? 'M00000' : 'M05066'));
    }

    /**
     * 确认订单
     * 参数：
     *     order_id             订单编号
     */
    function orderConfirm($input){
        if(!isset($input['order_id'])) return GeneralTool::createResult('','M00002');
        $result = SQL::update(['table' => 'orders',
                               'where' => ['order_id'   => $input['order_id'],
                                           'state'      => 2,
                                           'is_confirm' => 0],
                               'update' => ['is_confirm'   => 1,
                                            'confirm_time' => time()]]);
        return GeneralTool::createResult('', ($result ? 'M00000' : 'M00001'));
    }

    /**
     * 取消订单页
     * 参数：
     *     order_id。            订单编号
     */
    function order_cancel_blade($input){
        if(!isset($input['order_id'])) return GeneralTool::createResult('','M00002');
        $order  = $this->orderTool->get_order_info_from_table_orders(['order_id' => $input['order_id'],
                                                                      'is_cancel'=> 0,
                                                                      'state'    => 2]);
        if(!isset($order)) return ['state' => 'M00001', 'message' => '订单当前不能取消'];
        return GeneralTool::createResult($order, 'M00000');
    }

    /**
     * 订单取消处理
     * 参数：
     *     order_id         订单编号
     *     reason           原因
     */
    function order_cancel_from_backstage($input){
        if(!isset($input['order_id']) || !isset($input['reason']))
            return GeneralTool::createResult('', 'M00002');
        if(trim($input['reason']) == '')
            return ['state' => 'M00001', 'message' => '请填写取消原因'];
        $order  = $this->orderTool->get_order_info_from_table_orders(['order_id' => $input['order_id'],
                                                                      'is_cancel'=> 0,
                                                                      'state'    => 2]);
        if(!isset($order)) return ['state' => 'M00001', 'message' => '订单当前不能取消'];
        //记录取消原因
        $save_reason = OrderTool::save_reason_from_cancel($input);

        switch($order->pay_type){
            case 1:
                //微信
                $trade_type            = SQL::pluck(['table' => 'back_weixins',
                                                     'where' => ['transaction_id' => $order->trade_no],
                                                     'pluck' => 'trade_type']);
                if(!isset($trade_type) || ($trade_type != 'APP' && $trade_type !== 'JSAPI'))
                    return ['state' => 'M00001', 'message' => '未找到支付记录'];
                $data['out_refund_no'] = time() . '' . rand(100,999);
                $data['refund_fee']    = $order->total_fee;
                $data['total_fee']     = $order->total_fee;
                $data['transaction_id']= $order->trade_no;
                $data['trade_type']    = $trade_type;
                $result = PayTool::wx_refund($data);
                Log::info($result);
                if($result['return_code']=='FAIL'||$result['result_code']!='SUCCESS'){
                    return array('state'=>'M00001','message'=>$result['err_code_des']);
                }
                break;
            case 2:
                //支付宝
                return ['state'=>'M00003',
                        'result'=>['url'=> env('HOME_URL') . 'backstage/order/show-alirefund?order_id='.$input['order_id']]];
        }

        $input['iden'] = 0;
        $cancel = OrderTool::order_cancel($input,2);
        return GeneralTool::createResult('', $cancel);
    }

    /**
     * 支付宝退款展示页
     * 参数：
     *     order_id         订单编号
     */
    function show_alirefund($input){
        if(!isset($input['order_id'])) return GeneralTool::createResult('', 'M00002');
        $order  = $this->orderTool->get_order_info_from_table_orders(['order_id' => $input['order_id'],
                                                                      'is_cancel'=> 0,
                                                                      'state'    => 2]);
        if(!isset($order)) return ['state' => 'M00001', 'message' => '订单当前不能取消'];
        if($order->pay_type != 2) return ['state' => 'M00001', 'message' => '请选择支付宝支付的订单进行退款'];
        $arr['batch_no']    = date('YmdHis',time()).''.$order->order_number;
        $arr['bail_id']     = $order->order_id;
        $arr['detail_data'] = ''.$order->trade_no . '^' . $order->total_fee . '^' . $order->cancel_reason;
        return GeneralTool::createResult($arr,'M00000');
    }

    /**
     * 手工单
     */

    /**
     * 获取产品模版信息
     * 参数：
     *     product_temp_id    模版编号
     */
    function get_product_info($input){
        if(!isset($input['product_temp_id'])) return GeneralTool::createResult('','M00002');
        $temp = $this->orderTool->getProductTempByProductTempId($input['product_temp_id']);
        if(!isset($temp)) return GeneralTool::createResult('','M00000');
        $colours = $this->orderTool->productTempColoursByProductTempId($input['product_temp_id']);

        $size = count($colours) > 0 ?
                $this->orderTool->getProductTempSizeNamesByProductTempIdAndColourId($input['product_temp_id'],$colours[0]->colour_id):
                [];

        $position = count($colours) > 0 ?
                    $this->orderTool->productTempCustomZonePositionNamesByTempId($input['product_temp_id'],$colours[0]->colour_id):
                    [];

        return GeneralTool::createResult(['temp' => $temp,'colours' => $colours, 'size' => $size, 'position' => $position],'M00000');
    }

    /**
     * 获取产品模版颜色对应尺码
     * 参数：
     *     product_temp_id    模版编号
     *     colour_id          颜色变好
     */
    function findSize($input){
        if(!isset($input['product_temp_id']) || !isset($input['colour_id']))
            return GeneralTool::createResult('','M00002');
        $size = $this->orderTool->getProductTempSizeNamesByProductTempIdAndColourId($input['product_temp_id'],$input['colour_id']);
        $position = $this->orderTool->productTempCustomZonePositionNamesByTempId($input['product_temp_id'],$input['colour_id']);
        return GeneralTool::createResult(['size' => $size,'position' => $position],'M00000');
    }

    /**
     * 生成手工单
     * 参数:
     *     product_id           产品编号
     *     colour_name          颜色
     *     size_name            尺码
     *     quantity             数量
     *     message              备注
     *     consignee            收货人姓名
     *     phone                联系电话
     *     address              收货信息
     *     total_fee            订单金额
     */
    function create_order_by_backstage($input){
        if(!isset($input['detail']) ||
            !isset($input['consignee']) ||
            !isset($input['phone']) ||
            !isset($input['address']) ||
            !isset($input['total_fee']))
            return GeneralTool::createResult('','M00002');
        $result = GeneralTool::createResult('', 'M00003');
        try{
            $input['user_id'] = 1;
            $detail = $this->orderTool->get_order_detail_to_create($input);

            if($detail['state'] != 'M00000'){
                $result = GeneralTool::createResult('',$detail['state']);
                Throw new \Exception('订单详情数据有误');
            }

            //orders
            $arr['order_id']      = GeneralTool::only_no();
            $arr['buyer_id']      = 1;
            $arr['total_postage'] = $detail['total_postage'];
            $arr['total_fee']     = $input['total_fee'];
            $arr['pay_state']     = 2;
            $arr['type']          = 'order';
            $arr['state']         = 2;
            $arr['platform']      = 'Backstage';
            $arr['message']       = isset($input['message']) && trim($input['message']) != ''? bin2hex($input['message']) : '';
            $arr['back_message']  = '';
            $arr['substr']        = '';
            $arr['created_at']    = time();
            $arr['updated_at']    = $arr['created_at'];
            $orders = SQL::insert(['table'  => 'orders',
                                   'insert' => $arr]);
            $operation = $this->orderTool->order_operation_by_pay_success($arr);
            if(!$orders || !$operation){
                $result = GeneralTool::createResult('','M00001');
                Throw new \Exception('生成订单失败');
            }

            //order_express
            $ar['order_id']         = $arr['order_id'];
            $ar['address']          = $input['address'];
            $ar['consignee']        = $input['consignee'];
            $ar['phone']            = $input['phone'];
            $ar['order_express_id'] = '';
            $ar['express_name']     = '';
            $ar['express_id']       = '';
            $ar['created_at']       = time();
            $ar['updated_at']       = $ar['created_at'];
            $express = SQL::insert(['table' => 'order_express',
                                    'insert' => $ar]);
            if(!$express){
                $result = GeneralTool::createResult('','M05014');
                Throw new \Exception("记录收货信息失败");
            }
            //order_details
            $order_details = $this->orderTool->order_details_from_backstage($detail,$arr);
            if($order_details['state'] != 'M00000'){
                $result = $order_details;
                Throw new \Exception("记录收货信息失败");
            }

            return ['result' => ['order_id'=>$arr['order_id']],'state'=>'M00000','message' => '订单录入成功'];

        }catch(\Exception $e){
            Log::info($e);
            SQL::CatchDo();
            return $result;
        }finally{
            SQL::FinallyDo();
        }
    }


    function test($input){
        return GeneralTool::createResult('','M00000');
    }
}
